package com.example.demo16;

import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;

import java.io.*;
import java.net.URL;
import java.time.format.DateTimeParseException;

public class HelloController {
    @FXML
    private TextField titleField;
    @FXML
    private TextField authorField;
    @FXML
    private TextField editionField;
    @FXML
    private TextField genreField;
    @FXML
    private TextField searchField;
    @FXML
    private ToggleButton toggleThemeButton;
    @FXML
    private Button addB;
    @FXML
    private Button deleteB;
    @FXML
    private Button editB;
    @FXML
    private Button saveB;
    @FXML
    private TableView<Books> booksTable;
    @FXML
    private TableColumn<Books, String> titleColumn;
    @FXML
    private TableColumn<Books, String> authorColumn;
    @FXML
    private TableColumn<Books, String> editionColumn;
    @FXML
    private TableColumn<Books, String> genreColumn;

    // Инициализация колонок для TableView
    @FXML
    public void initialize() {
        titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));
        authorColumn.setCellValueFactory(new PropertyValueFactory<>("author"));
        editionColumn.setCellValueFactory(new PropertyValueFactory<>("editionAsString"));
        genreColumn.setCellValueFactory(new PropertyValueFactory<>("genre"));

        // Загрузка данных из файла
        loadBooksFromFile();
        // Добавление обработчика событий для кнопки добавления
        addB.setOnAction(this::addBooks);
        // Добавление обработчика событий для кнопки редактирования
        editB.setOnAction(event -> editBooks());
        // Добавление обработчика событий для кнопки сохранения
        saveB.setOnAction(this::saveBooksToFile);
        // Добавление обработчика событий для кнопки удаления
        deleteB.setOnAction(this::deleteSelectedRow);
        // Добавление обработчика событий для кнопки выборы
        toggleThemeButton.setOnAction(event -> switchTheme());
        // Добавление обработчика событий для кнопки поиска
        searchField.setOnAction(this::search);
    }

    @FXML
    private void addBooks(ActionEvent event) {
        try {
            // Проверка параметров книги
            if ((titleField.getText() == null) && (authorField.getText() == null)
                    && (editionField.getText() == null) && (genreField.getText() == null)) {
                Books newBook = new Books(
                        titleField.getText(),
                        authorField.getText(),
                        editionField.getText(),
                        genreField.getText()
                );
                booksTable.getItems().add(newBook);
                clearInputFields();
            }
            else {
                showAlert("Ошибка", "Необходимо ввести все данные о книге.");
            }
        }
        catch (DateTimeParseException e) {
            System.out.println("Ошибка при анализе времени: " + e.getMessage());
        }
    }

    @FXML // Метод для переключения темы
    private void switchTheme() {
        Scene scene = toggleThemeButton.getScene();
        if (scene != null) {
            // Очистка текущих стилей
            scene.getStylesheets().clear();

            // Проверка состояния ToggleButton
            if (toggleThemeButton.isSelected()) {
                // Переключение на темную тему
                URL darkThemeUrl = getClass().getResource("dark.css");
                if (darkThemeUrl != null) {
                    scene.getStylesheets().add(darkThemeUrl.toExternalForm());
                }
                else {
                    // Вывод ошибки, если файл не найден
                    System.err.println("Не удалось загрузить темную тему. Проверьте путь к файлу.");
                }
            }
            else {
                // Переключение на светлую тему
                URL lightThemeUrl = getClass().getResource("light.css");
                if (lightThemeUrl != null) {
                    scene.getStylesheets().add(lightThemeUrl.toExternalForm());
                }
                else {
                    // Вывод ошибки, если файл не найден
                    System.err.println("Не удалось загрузить светлую тему. Проверьте путь к файлу.");
                }
            }
        }
    }

    @FXML // Метод для сохранения всех тренировок в файл
    private void saveBooksToFile(ActionEvent actionEvent) {
        String homeDirectory = System.getProperty("user.home");
        String filePath = homeDirectory + "/books.txt"; // Путь для сохранения файла в домашней директории
        try (FileWriter fw = new FileWriter(filePath, false); // false для перезаписи файла
             BufferedWriter bw = new BufferedWriter(fw);
             PrintWriter out = new PrintWriter(bw)) {
            for (Books book: booksTable.getItems()) {
                // Проверка на null для параметров книги
                if (book.getTitle() != null && book.getAuthor() != null
                        && book.getEditionAsString() != null && book.getGenre() != null) {
                    out.println(book.getTitle() + ";" + book.getAuthor() + ";"
                            + book.getEditionAsString() + ";" + book.getGenre());
                }
                else {
                    System.out.println("Одна из книг не содержит необходимых параметров " +
                            "и не будет сохранена.");
                }
            }
        }
        catch (IOException e) {
            System.out.println("Ошибка при сохранении данных: " + e.getMessage());
        }
    }

    @FXML// Метод для загрузки данных из файла
    private void loadBooksFromFile() {
        String homeDirectory = System.getProperty("user.home");
        String filePath = homeDirectory + "/books.txt";
        try (FileReader fr = new FileReader(filePath);
             BufferedReader br = new BufferedReader(fr)) {
            String line;

            while ((line = br.readLine()) != null) {
                String[] booksData = line.split(";");
                // Проверяем, что строка содержит все необходимые данные
                if (booksData.length < 4) {
                    System.out.println("Неполные данные в строке: " + line);
                    continue; // Пропускаем эту строку и переходим к следующей
                }
                // Создание объекта Books из прочитанных данных
                Books book = new Books(
                        booksData[0], // название
                        booksData[1], // автор
                        booksData[2], // дата публикации
                        booksData[3] // жанр
                );
                booksTable.getItems().add(book); // Добавление объекта в таблицу
            }
        }
        catch (IOException | DateTimeParseException e) {
            System.out.println("Ошибка при загрузке данных: " + e.getMessage());
        }
    }

    @FXML
    private void search(ActionEvent event) { // Не работает :(
        showAlert("Ошибка", "Поиск не работает.");
        /*ObservableList<Books> bookData = FXCollections.observableArrayList();
        FilteredList<Books> filteredData = new FilteredList<>(bookData, b -> true);

        searchField.textProperty().addListener((observable, oldValue, newValue) -> {
            filteredData.setPredicate(book -> {
                if (newValue == null || newValue.isEmpty()) {
                    return true;
                }
                String[] bookInfo = newValue.toLowerCase().split(",");
                if (bookInfo.length == 2) {
                    if (book.getTitle().toLowerCase().contains(bookInfo[0].trim()) &&
                            book.getAuthor().toLowerCase().contains(bookInfo[1].trim())) {
                        return true;
                    }
                }
                else if (bookInfo.length == 1) {
                    if (book.getTitle().toLowerCase().contains(bookInfo[0].trim()) ||
                            book.getAuthor().toLowerCase().contains(bookInfo[0].trim())) {
                        return true;
                    }
                }
                return false;
            });
        });
        SortedList<Books> sortedData = new SortedList<>(filteredData);
        sortedData.comparatorProperty().bind(booksTable.comparatorProperty());
        booksTable.setItems(sortedData);*/
    }


    @FXML // Метод для справки
    public void showHelp() {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("Информация о приложении");
        alert.setHeaderText("Демо-приложение JavaFX");
        alert.setContentText("""
                Версия: 1.0
                Авторы: Тимур, Тимофей, Артем

                Приложение для поиска и редактирования книг.""");
        alert.showAndWait();
    }

    @FXML// Метод для отображения всплывающих уведомлений
    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    @FXML // Метод для удаления данных из таблицы
    private void deleteSelectedRow(ActionEvent event) {
        Books selectedBook = booksTable.getSelectionModel().getSelectedItem();
        if (selectedBook != null) {
            booksTable.getItems().remove(selectedBook);
        }
        else {
            showAlert("Ошибка", "Необходимо выбрать книгу для удаления.");
        }
    }

    @FXML // Метод для редактирования выбранной книги
    private void editBooks() {
        // Получаем выбранную книгу
        Books selectedBook = booksTable.getSelectionModel().getSelectedItem();
        if (selectedBook != null) {
            // Отображаем данные выбранной книги в полях ввода
            titleField.setText(selectedBook.getTitle());
            authorField.setText(selectedBook.getAuthor());
            editionField.setText(selectedBook.getEditionAsString());
            genreField.setText(selectedBook.getGenre());
            // Делаем кнопки "Добавить" и "Удалить" недоступной, а кнопку "Сохранить" доступной
            addB.setDisable(false);
            deleteB.setDisable(true);
            editB.setDisable(false);
            // Устанавливаем действие для кнопки "Сохранить"
            addB.setOnAction(event -> saveEditedBooks(selectedBook));
        }
        else {
            // Если тренировка не выбрана, выводим сообщение об ошибке
            showAlert("Ошибка", "Необходимо выбрать книгу для редактирования.");
        }
    }

    @FXML // Метод для сохранения отредактированных данных книги
    private void saveEditedBooks(Books bookToEdit) {
        // Проверяем, что в поля ввода внесены изменения
        if (!titleField.getText().isEmpty() || !authorField.getText().isEmpty()
                || !editionField.getText().isEmpty() || !genreField.getText().isEmpty()) {
            bookToEdit.setTitle(titleField.getText());
            bookToEdit.setAuthor(authorField.getText());
            bookToEdit.setEditionAsString(editionField.getText());
            bookToEdit.setGenre(genreField.getText());
        }
        else {
            // Если изменения не обнаружены, показываем предупреждение и прерываем выполнение метода
            showAlert("Ошибка", "Названия и автор не выбраны.");
            return;
        }
        // Обновляем данные книги новыми значениями из полей ввода
        bookToEdit.setTitle(titleField.getText());
        bookToEdit.setAuthor(authorField.getText());
        bookToEdit.setEditionAsString(editionField.getText());
        bookToEdit.setGenre(genreField.getText());
        // Обновляем таблицу с новыми данными
        booksTable.refresh();
        // Очищаем поля ввода и делаем кнопки "Добавить" и "Удалить" снова доступной
        clearInputFields();
        addB.setDisable(false);
        deleteB.setDisable(false);
        editB.setDisable(true);
    }

    // Метод для очистки полей ввода
    private void clearInputFields() {
        titleField.clear();
        authorField.clear();
        editionField.clear();
        genreField.clear();
    }

    public static class Books {
        private final StringProperty title;
        private final StringProperty author;
        private final StringProperty edition;
        private final StringProperty genre;

        public Books(String title, String author, String edition, String genre) {
            this.title = new SimpleStringProperty(title);
            this.author = new SimpleStringProperty(author);
            this.edition = new SimpleStringProperty(edition);
            this.genre = new SimpleStringProperty(genre);
        }

        // Геттеры и сеттеры
        public String getTitle() {
            return title.get();
        }

        public void setTitle(String title) {
            this.title.set(title);
        }

        public String getAuthor() {
            return author.get();
        }

        public void setAuthor(String author) {
            this.author.set(author);
        }

        public String getEditionAsString() { // Добавлен новый геттер
            return edition.get();
        }

        public void setEditionAsString(String duration) { // Добавлен новый сеттер
            this.edition.set(duration);
        }

        public String getGenre() {
            return genre.get();
        }

        public void setGenre(String genre) {
            this.genre.set(genre);
        }
    }
}